/* Copyright (c) 2022 渝州大数据实验室
 *
 * Lanius is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *
 *     http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
/**
 * @desc 菜单数据的封装TS
 * @fileName menu.ts
 * @author zoujunjie@yzbdl.ac.cn
 * @date 2022-4-8
 */

interface IMenuItem {
  text: string;
  key: string;
  path?: string;
  icon?: string;
  children?: IMenuItem[];
}

let getAssetsLayoutMenuUrl = (key: string) => {
  return new URL(`../assets/img/layout/menu/icon-${key}.png`, import.meta.url)
    .href;
};

const taskScheduleMenu: IMenuItem[] = [
  {
    key: "/task-schedule",
    icon: getAssetsLayoutMenuUrl("schedule"),
    text: "任务调度",
    children: [
      {
        text: "调度总览",
        icon: getAssetsLayoutMenuUrl("dashboard"),
        path: "/task-schedule/dashboard",
        key: "/tatistic",
      },
      {
        text: "资源管理",
        icon: getAssetsLayoutMenuUrl("resource"),
        key: "/task-schedule/resource-management",
        children: [
          {
            text: "服务器管理",
            path: "/task-schedule/host-config",
            key: "/resource/server",
          },
          {
            text: "服务节点",
            path: "/task-schedule/service-node",
            key: "/resource/serverProgram",
          },
          {
            text: "资源配置",
            path: "/task-schedule/allocation-resources",
            key: "/resource/taskResourceConfig",
          },
          {
            text: "任务资源",
            path: "/task-schedule/resource",
            key: "/resource/taskResource",
          },
        ],
      },
      {
        text: "任务编排",
        icon: getAssetsLayoutMenuUrl("arrange"),
        path: "/task-schedule/arrangement",
        key: "/task",
      },
      {
        text: "任务实例",
        icon: getAssetsLayoutMenuUrl("instance"),
        path: "/task-schedule/task-instance",
        key: "/task/instance",
      },
    ],
  },
];

const systemManagementMenu: IMenuItem[] = [
  {
    key: "/system-management",
    icon: getAssetsLayoutMenuUrl("setting"),
    text: "系统管理",
    children: [
      {
        text: "角色管理",
        icon: getAssetsLayoutMenuUrl("role"),
        path: "/system-management/role",
        key: "/role",
      },
      {
        text: "成员管理",
        icon: getAssetsLayoutMenuUrl("user"),
        path: "/system-management/user-manage",
        key: "/user",
      },
      {
        text: "日志管理",
        icon: getAssetsLayoutMenuUrl("log"),
        path: "/system-management/log",
        key: "/userLog",
      },
      // {
      //   text: "消息管理",
      //   icon: getAssetsLayoutMenuUrl("log"),
      //   path: "/system-management/message",
      //   key: "/userLog",
      // },
      // {
      //   text: "系统参数",
      //   icon: getAssetsLayoutMenuUrl("log"),
      //   path: "/system-management/config",
      //   key: "/userLog",
      // },
    ],
  },
];

const adminMenu: IMenuItem[] = [
  {
    key: "/admin/system-management",
    icon: getAssetsLayoutMenuUrl("setting"),
    text: "系统管理",
    children: [
      {
        text: "组织管理",
        icon: getAssetsLayoutMenuUrl("organization"),
        path: "/admin/system-management/organization",
        key: "/admin/system-management/organization",
      },
      {
        text: "账号管理",
        icon: getAssetsLayoutMenuUrl("user"),
        path: "/admin/system-management/user",
        key: "/admin/system-management/user",
      },
    ],
  },
];

let findMenuItemByPath = (
  path: string,
  rootMenuItem?: IMenuItem,
  menuList?: IMenuItem[]
): IMenuItem | null => {
  if (menuList && menuList.length > 0 && path) {
    let menu = menuList.find((x) => x.path == path);
    if (menu) {
      return (
        rootMenuItem ||
        ({
          path: menu.path,
          text: menu.text,
          icon: menu.icon,
          key: menu.key,
        } as IMenuItem)
      );
    }

    for (let i = 0; i < menuList.length; i++) {
      let item: IMenuItem = menuList[i];
      let menu: IMenuItem | null = findMenuItemByPath(
        path,
        rootMenuItem,
        item.children
      );
      if (menu) {
        return rootMenuItem || menu;
      }
    }
  }
  return null;
};

let findParentMenuItem = (
  child: IMenuItem,
  list: IMenuItem[]
): IMenuItem | null => {
  if (child) {
    if (list.find((x) => x.key == child.key)) {
      return null;
    } else {
      for (let i = 0; i < list.length; i++) {
        let item = list[i];
        if (item.children?.find((x2) => x2.key == child.key)) {
          return {
            path: item.path,
            text: item.text,
            icon: item.icon,
            key: item.key,
          } as IMenuItem;
        }
        let parentItem = findParentMenuItem(child, item.children || []);
        if (parentItem) {
          return {
            path: parentItem.path,
            text: parentItem.text,
            icon: parentItem.icon,
            key: parentItem.key,
          } as IMenuItem;
        }
      }
    }
  }
  return null;
};

let getAncestorList = (
  childMenuItem: IMenuItem,
  ancestorList: IMenuItem[]
): IMenuItem[] => {
  ancestorList.unshift(childMenuItem);
  let parentItem = findParentMenuItem(childMenuItem, menus);
  if (parentItem) {
    return getAncestorList(parentItem, ancestorList);
  } else {
    return ancestorList;
  }
};

const getBreadcrumbByPath = (currentPath: string): IMenuItem[] => {
  if (currentPath) {
    let menu = findMenuItemByPath(
      currentPath.toLowerCase().trim(),
      undefined,
      menus
    );
    if (menu) {
      return getAncestorList(menu, []);
    }
  }
  return [];
};

let getKeys = (menuList: IMenuItem[], keys: string[]): void => {
  if (menuList && menuList.length > 0) {
    menuList.forEach((x) => {
      keys.push(x.key);
      getKeys(x.children || [], keys);
    });
  }
};

const getAllKeys = (): string[] => {
  let keys: string[] = [];
  getKeys(menus, keys);
  return Array.from(new Set(keys));
};

const adminUserMenus: IMenuItem[] = [...adminMenu];
const organizationUserMenus: IMenuItem[] = [
  ...taskScheduleMenu,
  ...systemManagementMenu,
];
const menus: IMenuItem[] = [...adminUserMenus, ...organizationUserMenus];

const getOrganizationUserMenus = (
  menuKeyPermissions: string[]
): IMenuItem[] => {
  let check = (menuList: IMenuItem[]): IMenuItem[] => {
    let tempList: IMenuItem[] = menuList.filter((item) => {
      return !item.path || menuKeyPermissions.find((x) => x == item.key);
    });
    if (tempList && tempList.length > 0) {
      tempList.forEach((item) => {
        if (item.children && item.children.length > 0) {
          item.children = check(item.children);
        }
      });
      tempList = tempList.filter(
        (x) => x.path || (x.children && x.children.length > 0)
      );
    }
    return tempList;
  };

  return check(JSON.parse(JSON.stringify(organizationUserMenus)));
};

const getOrganizationUserMenuItemByPath = (path: string): IMenuItem | null => {
  return getMenuListItemByPath(organizationUserMenus, path);
};

const getMenuListItemByPath = (
  list: IMenuItem[],
  path: string
): IMenuItem | null => {
  let find = (menuList: IMenuItem[]): IMenuItem | null => {
    let item = menuList.find((x) => x.path == path);
    if (item) {
      return item;
    }
    for (let i = 0; i < menuList.length; i++) {
      let menu = menuList[i];
      if (menu.children && menu.children.length > 0) {
        let temp = find(menu.children);
        if (temp) {
          return temp;
        }
      }
    }
    return null;
  };
  return find(list);
};

export {
  IMenuItem,
  adminUserMenus,
  organizationUserMenus,
  getBreadcrumbByPath,
  getAllKeys,
  getOrganizationUserMenus,
  getMenuListItemByPath,
  getOrganizationUserMenuItemByPath,
};
